﻿// cpp_study_thread.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

/*

thread 不能返回值，需要将结果存放的引用传入
async基于future,可以返回结果

*/

#include <iostream>
#include <thread>
#include <future>
#include "UseThreadCount.h"
#include "UseFunctorCount.h"

#include "UseMutex.h"
#include "UseLockGuard.h"
#include "UseMultiMutexBetter.h"
#include "UseAtomic.h"
#include <random>

using namespace std;
//---------------base 1---------------------
void add_count(uint64_t& result, uint64_t start, uint64_t end);
uint64_t add_count2(uint64_t start, uint64_t end);
void use_functor_count();
void use_lambda_count();
void use_async_count();
//---------------base 2---------------------
void use_mutex();
void use_lock_guard();
void lock_guard_cst();
void use_multi_mutex();
//--------------base 3----------------------
void use_atmoic();

int main()
{
    //----------------base 1-------------------
    //uint64_t result = 0;
    //std::thread t(add_count, std::ref(result), 1, 1000 * 1000 * 1000);
    //t.join();
    //cout << "result: " << result << endl;
    //UseThreadCount utc(100, 1, 1000 * 1000 * 1000);
    //cout << utc.get_count() << endl;
    // use_functor_count();
    // use_lambda_count();
    //use_async_count();

    //----------------base 2-------------------
    // use_mutex();
    // use_lock_guard();
    // lock_guard_cst();
    // use_multi_mutex();

    //----------------base 3-------------------
    use_atmoic();

    return 0;
}

void add_count(uint64_t& result, uint64_t start, uint64_t end) {

    for (uint64_t i = start; i <= end; i++) {
        result += i;
    }
    
}

void use_functor_count() {
    
    UseFunctorCount* func = new UseFunctorCount();
    uint64_t result = 0;
    thread t(ref(*func), ref(result), 1, 100);

    t.join();

    cout << "result: " << result << endl;

}

void use_lambda_count() {

    uint64_t result = 0;
    uint64_t start = 1;
    uint64_t end = 100;
    thread t([&result, start, end]{
            for (uint64_t i = start; i <= end; i++) {
                result += i;
            }
        });

    t.join();

    cout << "result: " << result << endl;

}

uint64_t add_count2(uint64_t start, uint64_t end) {
    uint64_t result = 0;
    for (uint64_t i = start; i <= end; i++) {
        result += i;
    }

    return result;
}

void use_async_count() {

    future<uint64_t> t = async(add_count2, 1, 100);
    cout << "result: " << t.get() << endl;

}

void use_mutex() {

    UseMutex useMutex;
    vector<thread> join_list;

    for (int i = 0; i < 10; i++) {
        join_list.push_back(thread(&UseMutex::inc, useMutex));
    }

    for (auto &t : join_list) {
        t.join();
    }

    cout << "count: " << useMutex.get_count() << endl;
}

void use_lock_guard() {

    UseLockGuard useLockGuard;
    vector<thread> join_list;

    for (int i = 0; i < 10; i++) {
        join_list.push_back(thread(&UseLockGuard::inc, useLockGuard));
    }

    for (auto& t : join_list) {
        t.join();
    }

    cout << "count: " << useLockGuard.get_count() << endl;
}

void use_multi_mutex() {

    UseMultiMutexBetter useMulti;
    vector<thread> join_list;

    for (int i = 0; i < 10; i++) {
        join_list.push_back(thread(&UseMultiMutexBetter::inc, useMulti));
    }

    for (auto& t : join_list) {
        t.join();
    }

    cout << "count: " << useMulti.get_count() << endl;
}

void lock_guard_cst() {

    static mutex m;
    static int x = 0;
    static int y = 0;
    thread t([] {

        x = 1;
        lock_guard<mutex> lg(m);
        y = 2;
        });
    thread t2([] {
        
        this_thread::sleep_for(chrono::seconds(1));

        lock_guard<mutex> lg(m);
        y = x + 2;
        });

    t.join();
    t2.join();

    cout << "x = " << x << " y = " << y << endl;

}

void use_atmoic() {

    UseAtomic useAtomic;
    vector<thread> join_list;
    for (int i = 0; i < 1000; i++) {
        join_list.push_back(thread(&UseAtomic::inc, useAtomic));
    }
    for (auto &t : join_list) {
        t.join();
    }

    cout << "count: " << useAtomic.getCount() << endl;
}
